/*
 Copyright 2013--Present JMM_PROGNAME
 
 This file is distributed under the terms of the JMM_PROGNAME License.
 
 You should have received a copy of the JMM_PROGNAME License.
 If not, see <JMM_PROGNAME WEBSITE>.
*/
// CREATED    : 11/8/2013
// LAST UPDATE: 11/8/2013

#include "NeuralNet.hpp"


//========================================================================
//========================================================================
//
// NAME: double NEURAL_NET::parse_TS(TRAINING_SET TS, std::vector<std::vector<double>> &NN_out)
//
// DESC: Reduces the input, as a result of pre-processing PCA data-reduction.
//
//========================================================================
//========================================================================
void NEURAL_NET::reduce_input()
{
    // SINCE INPUT NEURONS ARE DEFINED BEFORE ALL OTHERS, WE CAN SIMPLY DELETE ALL CONNECTIONS FROM transf_ninp TO (ninp-1) ...
    
    // FIRST CLEAR ALL OF THE LINKS OUT FROM THE REDUCED INPUT NODES ...
    for( int i = m_transf_ninp; i < m_ninp; ++i )
    {
        m_links_out[i].clear();
    }

    // THEN LOOP OVER ALL LINKS AND REMOVE ALL THAT HAVE A REDUCED INPUT NODE AS SOURCE ...
    for( auto it = m_links.begin(); it != m_links.end(); )
    {
        if( (it->source >= m_transf_ninp) && (it->source < m_ninp) )
        {
            int l = std::distance( m_links.begin(), it );

            for( decltype(m_neurons.size()) j = 0; j < m_neurons.size(); ++j )
            {
                if( j == it->source )
                {
                    continue;
                }
                
                for( auto it2 = m_links_in[j].begin(); it2 != m_links_in[j].end(); )
                {
                    if( m_links[*it2].source == it->source )
                    {
                        it2 = m_links_in[j].erase(it2);
                    }
                    else
                    {
                        ++it2;
                    }
                }
                
                for( decltype(m_links_in[j].size()) k = 0; k < m_links_in[j].size(); ++k )
                {
                    if( m_links_in[j][k] > l )
                    {
                        --m_links_in[j][k];
                    }
                }
                
                for( decltype(m_links_out[j].size()) k = 0; k < m_links_out[j].size(); ++k )
                {
                    if( m_links_out[j][k] > l )
                    {
                        --m_links_out[j][k];
                    }
                }
            }
            
            it = m_links.erase(it);
        }
        else
        {
            ++it;
        }
    }
    
    // ****
//    m_isTrained = true;
//    draw_NN(*this);
//    m_isTrained = false;
    // ****
}